package no.awi.wpd.unit.model;

import no.awi.wpd.combat.model.InitiativeStep;
import no.awi.wpd.probability.ProbabilityDistribution;
import no.awi.wpd.probability.ProbabilityFunctions;
import no.awi.wpd.probability.WarhammerProbabilityFunctions;
import org.springframework.orm.toplink.AbstractSessionFactory;

import static no.awi.wpd.probability.WarhammerProbabilityFunctions.*;

public class Profile {
	
	private static final int NO_SAVE = 7;

    private String name;
	private int ws = 3;
	private int st = 3;
	private int to = 3;
	private int wo = 1;
	private int in = 4;
	private int at = 1;
	private int ld = 7;
	private int us = 1;
	private int asv = NO_SAVE;
	private int wsv = NO_SAVE;
    private TroopType type = TroopType.INFANTRY;
	private boolean asf = false;
	private boolean asl = false;
	private boolean rerollToHit = false;
	private boolean rerollToWound = false;
	private boolean poison = false;
	private boolean killingBlow = false;
	private ProbabilityDistribution multipleWounds = ProbabilityDistribution.ONE();
	private ProbabilityDistribution impactHits = ProbabilityDistribution.ZERO();
    private boolean coldBlooded = false;
    private boolean frenzy;

    public boolean rerollToHit(Profile attackee) {
        return rerollToHit || (getInitiativeStep() == InitiativeStep.ASF
                && !(attackee.getInitiativeStep() == InitiativeStep.ASF) && getIn() >= attackee.getIn());
    }

    public int getWs() {
        return ws;
    }

    public Profile ws(int ws) {
        this.ws = ws;
        return this;
    }

    public int getSt() {
        return st;
    }

    public Profile st(int s) {
        this.st = s;
        return this;
    }

    public int getTo() {
        return to;
    }

    public Profile to(int t) {
        this.to = t;
        return this;
    }

    public int getWo() {
        return wo;
    }

    public Profile wo(int w) {
        this.wo = w;
        return this;
    }

    public int getIn() {
        return in;
    }

    public Profile in(int i) {
        this.in = i;
        return this;
    }

    public int getAt() {
        return at;
    }

    public Profile at(int a) {
        this.at = a;
        return this;
    }

    public int getLd() {
        return ld;
    }

    public Profile ld(int ld) {
        this.ld = ld;
        return this;
    }

    public int getAsv() {
        return asv;
    }

    public Profile armoursave(int armourSave) {
        this.asv = armourSave;
        return this;
    }

    public int getWsv() {
        return wsv;
    }

    public Profile wardsave(int wardSave) {
        this.wsv = wardSave;
        return this;
    }

    public TroopType getType() {
        return type;
    }

    public Profile type(TroopType type) {
        this.type = type;
        return this;
    }

    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        if (name != null)
            sb.append(name + ": ");
        sb.append("WS: " + ws + ", ");
        sb.append("St: " + st + ", ");
        sb.append("To: " + to + ", ");
        sb.append("Wo: " + wo + ", ");
        sb.append("In: " + in + ", ");
        sb.append("At: " + at + ", ");
        sb.append("Ld: " + ld + ", ");
        sb.append("US: " + us + ", ");
    
         sb.append("ASv: " + (asv == NO_SAVE ? "-" : asv) + ", ");
        sb.append("WSv: " + (wsv == NO_SAVE ? "-" : wsv));
        return sb.toString();
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + asv;
        result = prime * result + at;
        result = prime * result + in;
        result = prime * result + ld;
        result = prime * result + st;
        result = prime * result + to;
        result = prime * result + wsv;
        result = prime * result + ws;
        result = prime * result + wo;
        result = prime * result + us;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        final Profile other = (Profile) obj;
        if (asv != other.asv)
            return false;
        if (at != other.at)
            return false;
        if (in != other.in)
            return false;
        if (ld != other.ld)
            return false;
        if (st != other.st)
            return false;
        if (to != other.to)
            return false;
        if (wsv != other.wsv)
            return false;
        if (ws != other.ws)
            return false;
        if (wo != other.wo)
            return false;
        if (us != other.us)
        	return false;
        return true;
    }

    public boolean isColdBlooded() {
        return coldBlooded;
    }

    public Profile setFrenzy() {
        frenzy = true;
        return this;
    }

    public Profile setAsl() {
        asl = true;
        return this;
    }

    public Profile setAsf() {
        asf = true;
        return this;
    }

    public String getName() {
        return name;
    }

    public Profile name(String name) {
        this.name = name;
        return this;
    }

    public InitiativeStep getInitiativeStep() {
        if (asl && !asf) return InitiativeStep.ASL;
        if (asf && !asl) return InitiativeStep.ASF;
        return InitiativeStep.fromIn(in);
    }

    public Profile setRerollToHit() {
        rerollToHit = true;
        return this;
    }
}
